package org.centsuse.intention_spring.invention.config.scenes.processor;

import com.fasterxml.jackson.core.JsonProcessingException;
import dev.langchain4j.data.message.AiMessage;
import dev.langchain4j.data.message.UserMessage;
import dev.langchain4j.memory.ChatMemory;
import dev.langchain4j.model.chat.ChatLanguageModel;
import lombok.Data;
import lombok.ToString;
import lombok.extern.slf4j.Slf4j;
import org.centsuse.intention_spring.invention.config.scenes.SceneConfig;
import org.centsuse.intention_spring.invention.entities.contexts.ContextManager;
import org.centsuse.intention_spring.invention.entities.contexts.DialogueContext;
import org.centsuse.intention_spring.invention.entities.http.ChatResponse;
import org.centsuse.intention_spring.invention.factory.ModelFactory;
import org.centsuse.intention_spring.invention.factory.SceneFactory;
import org.centsuse.intention_spring.invention.utils.ChatbotUtils;
import org.centsuse.intention_spring.invention.utils.DataformatUtils;
import org.centsuse.intention_spring.invention.utils.PromptUtils;
import org.springframework.stereotype.Component;

import java.util.Map;

// 通用处理器实现
@Data
@Slf4j
@Component
@ToString
public class CommonProcessor extends AbstractSceneProcessor<DialogueContext> {

    /** 模型工厂，提供对话所需要的模型 */
    private ModelFactory modelFactory;

    /** 对话上下文，提供当前的对话信息：包括场景，槽值，历史对话 */
    private ContextManager contextManager;

    /** 场景配置 */
    private Map<String, SceneConfig> sceneConfigMap;

    /**
     * @description 构造函数
     * @param modelFactory  modelFactory
     * @param contextManager contextManager
     * @param sceneFactory sceneFactory
     */
    public CommonProcessor(ModelFactory modelFactory, ContextManager contextManager, SceneFactory sceneFactory) {
        this.modelFactory = modelFactory;
        this.contextManager = contextManager;
    }

    @Override
    public ChatResponse process(String userInput, DialogueContext context) throws JsonProcessingException {
        log.info("[CommonProcessor][process] userInput {}, context {}", userInput, context);
        String purpose = context.getCurrentPurpose();
        ChatMemory chatMemory = context.getMemory();
        SceneConfig sceneConfig = sceneConfigMap.get(purpose);
        if (sceneConfig != null) {
            String fullPrompt = PromptUtils.getSlotUpdateMessage(sceneConfig.getName(), sceneConfig.getParameters(), (String) sceneConfig.getExample(), context.getSlots().values(), userInput);
            ChatLanguageModel chatLanguageModel = modelFactory.getDefaultModel();
            String result = chatLanguageModel.chat(fullPrompt);
            chatMemory.add(new UserMessage(userInput));
            chatMemory.add(new AiMessage(result));
            String cleanResult = DataformatUtils.extractAfterLastThink(result);
            ChatbotUtils.updateSlot(ChatbotUtils.extractJsonFromString(cleanResult), context.getSlots());
            log.info("[CommonProcessor][process] result {}, cleanResult {}", result, cleanResult);
            log.info("[CommonProcessor][process] context {}", context);
            log.info("[CommonProcessor][process] chatMemory {}", chatMemory.messages());
            // 检查参数是否足够，如果够，则调用api，否则，继续追问
            if (ChatbotUtils.isSlotFullyFilled(context.getSlots().values())) {
                log.info("[CommonProcessor][process] slotFullyFilled, 调用api");
                return new ChatResponse(purpose + "处理完毕", context.getSessionId());
            } else {
                String prompt = PromptUtils.getSlotQueryUserMessage(sceneConfig.getName(), context.getSlots().values(), userInput);
                String answer = chatLanguageModel.chat(prompt);
                log.info("[CommonProcessor][process] slotNotFullyFilled, prompt {}, answer {}", prompt, answer);
                return new ChatResponse(answer, context.getSessionId());
            }
        }

//                # 处理用户输入，更新槽位，检查完整性，以及与用户交互
//        # 先检查本次用户输入是否有信息补充，保存补充后的结果   编写程序进行字符串value值diff对比，判断是否有更新
//                message = get_slot_update_message(self.scene_name, self.slot_dynamic_example, self.slot_template, user_input)  # 优化封装一下 .format  入参只要填input
//        new_info_json_raw = send_message(message, user_input)
//        current_values = extract_json_from_string(new_info_json_raw)
//        logging.debug('current_values: %s', current_values)
//        logging.debug('slot update before: %s', self.slot)
//        update_slot(current_values, self.slot)
//        logging.debug('slot update after: %s', self.slot)
//        # 判断参数是否已经全部补全
//        if is_slot_fully_filled(self.slot):
//        return self.respond_with_complete_data()
//        else:
//        return self.ask_user_for_missing_data(user_input)

//        String prompt = PromptUtils.getSlotUpdateMessage(this.getName(), this.getDynamicExample(), this.getSlotTemplates(), userInput);
//        ChatLanguageModel chatLanguageModel = modelFactory.getDefaultModel();
//        String answer = chatLanguageModel.chat(prompt);
//        List<Map<String, Object>> currentValue = ChatbotUtils.extractJsonFromString(answer);
//        return chatLanguageModel.chat(prompt);
        return new ChatResponse(purpose + "场景异常", context.getSessionId());
    }

    @Override
    public void initialize(SceneConfig config) {
        // TODO
    }
}
